/*
 * @Author: qinuoyun
 * @Date:   2019-11-02 11:35:39
 * @Last Modified by:   qinuoyun
 * @Last Modified time: 2019-11-27 11:15:36
 */

import md5 from 'js-md5';

function isArray(o) {
  return Object.prototype.toString.call(o) == '[object Array]';
}

function isObject(data) {
  const object = Object.prototype.toString;
  if (object.call(data) == "[object Object]") {
    return true;
  } else {
    return false;
  }
}

/**
 * 深度拷贝
 * @param  {[type]} obj   [description]
 * @param  {Array}  cache [description]
 * @return {[type]}       [description]
 */
export function deepCopy(obj, cache = []) {
  // just return if obj is immutable value
  if (obj === null || typeof obj !== 'object') {
    return obj
  }

  // if obj is hit, it is in circular structure
  const hit = find(cache, c => c.original === obj)
  if (hit) {
    return hit.copy
  }

  const copy = Array.isArray(obj) ? [] : {}
  // put the copy into cache at first
  // because we want to refer it in recursive deepCopy
  cache.push({
    original: obj,
    copy
  })

  Object.keys(obj).forEach(key => {
    copy[key] = deepCopy(obj[key], cache)
  })

  return copy
}

/**
 * 正向存储
 * @param  {[type]} array [description]
 * @return {[type]}       [description]
 */
export function forward(obj, cache = []) {
  //  判断如果为或者不为对象则直接返回
  if (obj === null || typeof obj !== 'object') {
    return obj
  }

  // 判断存在 则拷贝数据返回
  const hit = find(cache, c => c.original === obj)
  if (hit) {
    return hit.copy
  }
  const copy = Array.isArray(obj) ? [] : {}

  cache.push({
    original: obj,
    copy
  })
  Object.keys(obj).forEach(key => {
    switch (key) {
      case 'components':
        copy[key] = md5(obj[key].__file ? obj[key].__file : "");
        break;
      case 'tool':
        copy[key] = md5(obj[key].__file ? obj[key].__file : "");
        break;
      default:
        copy[key] = forward(obj[key], cache)
    }

  })
  return copy
}



/**
 * 反向解析
 * @param  {[type]} array [description]
 * @return {[type]}       [description]
 */
export function reverse(obj, library, cache = []) {
  //  判断如果为或者不为对象则直接返回
  if (obj === null || typeof obj !== 'object') {
    return obj
  }

  // 判断存在 则拷贝数据返回
  const hit = find(cache, c => c.original === obj)
  if (hit) {
    return hit.copy
  }
  const copy = Array.isArray(obj) ? [] : {}

  cache.push({
    original: obj,
    copy
  })
  let _handle, _tool = "";
  Object.keys(obj).forEach(key => {
    switch (key) {
      case 'components':
        _handle = obj[key];
        copy[key] = library[_handle] ? library[_handle] : "";
        break;
      case 'tool':
        _tool = obj[key];
        copy[key] = library[_tool] ? library[_tool] : false;
        break;
      default:
        copy[key] = reverse(obj[key], library, cache)
    }

  })
  return copy
}
